#include <iostream>
#include <fstream>
#include <sstream>
#include "TeeBuf.h"
#include "ScopedStreamBufAssign.h"
#include "UpperCaseStreamBuf.h"
#include "BreakingBuf.h"
#include "ResourceStream.h"

int main()
{
	using namespace std;
	string str;

	{
		ofstream file("data.txt");
		ofstream file2("data2.txt");
		ostringstream ss;

		// tbuf will write to both file and cout
		teebuf tbuf(file.rdbuf(), cout.rdbuf());

		// tbuf2 will write to file2 tbuf and tbuf
		teebuf tbuf2(file2.rdbuf(), &tbuf);

		// tbuf3 will write to booth ss and tbuf2
		teebuf tbuf3(ss.rdbuf(), &tbuf2);

		// replace cout's streambuf with tbuf3
		scoped_streambuf_assignment ssa(cout, &tbuf3);

		// start writing
		cout << "Hello world!" << endl;

		str = ss.str();
	}
	{
		uppercase_buf up(cout.rdbuf());
		cout << "hello world" << endl;
	}
	{
		wuppercase_buf up(wcout.rdbuf());
		wcout << L"hello wide" << endl;
	}
	{
		
		ofstream file("break.txt");
		breaking_buf bb(file.rdbuf());
		ostream os(&bb);
		os << "123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF" << endl;
	}
	{
		wofstream file("wbreak.txt");
		wbreaking_buf bb(file.rdbuf());
		wostream os(&bb);
		os << L"123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF" << endl;
	}
	{
		CResource res;
		{
			CResourceStreamBuf rsb(res);
			ostream os(&rsb);
			os << "Hello resource!" << endl;
			cout << res.Content() << endl;
		}
		{
			CResourceStreamBuf rsb(res);
			istream is(&rsb);
			string s;
			is >> s;
			cout << s << endl;
		}
	}

    return 0;
}
